#! /bin/make -f
# @file
# @brief Makefile规则：ARM GCC
# @author
# + 隐星魂 (Roy Sun) <xwos@xwos.tech>
# @copyright
# + Copyright © 2015 xwos.tech, All Rights Reserved.
# > Licensed under the Apache License, Version 2.0 (the "License");
# > you may not use this file except in compliance with the License.
# > You may obtain a copy of the License at
# >
# >         http://www.apache.org/licenses/LICENSE-2.0
# >
# > Unless required by applicable law or agreed to in writing, software
# > distributed under the License is distributed on an "AS IS" BASIS,
# > WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# > See the License for the specific language governing permissions and
# > limitations under the License.
#

TARGET ?= XWOS
XWTC ?= $(shell xwtcwd)
XWTC := $(subst \,/,$(XWTC))
export XWTC
ARMTOOLS ?= $(XWTC)/arm
CROSS_COMPILE ?= $(ARMTOOLS)/bin/arm-none-eabi-
CC := $(CROSS_COMPILE)gcc
CXX := $(CROSS_COMPILE)g++
AS := $(CROSS_COMPILE)gcc -x assembler-with-cpp
OBJCOPY := $(CROSS_COMPILE)objcopy
OD := $(CROSS_COMPILE)objdump
AR := $(CROSS_COMPILE)ar
LD := $(CROSS_COMPILE)gcc
SIZE := $(CROSS_COMPILE)size
LUA2HEX := python3 xwbs/util/py/lua2hex.py
CP := cp -ap
RM := -rm
MSG := echo -e

ARCH_INCDIRS += $(ARCH_INCDIRS_gcc)
ARCH_AFLAGS += $(ARCH_AFLAGS_gcc)
ARCH_CFLAGS += $(ARCH_CFLAGS_gcc)
ARCH_CXXFLAGS += $(ARCH_CXXFLAGS_gcc)
ARCH_LDFLAGS += $(ARCH_LDFLAGS_gcc)
ARCH_ASRCS += $(ARCH_ASRCS_gcc)
ARCH_CSRCS += $(ARCH_CSRCS_gcc)
ARCH_CXXSRCS += $(ARCH_CXXSRCS_gcc)
ARCH_EOBJS += $(ARCH_EOBJS_gcc)

CPU_INCDIRS += $(CPU_INCDIRS_gcc)
CPU_AFLAGS += $(CPU_AFLAGS_gcc)
CPU_CFLAGS += $(CPU_CFLAGS_gcc)
CPU_CXXFLAGS += $(CPU_CXXFLAGS_gcc)
CPU_LDFLAGS += $(CPU_LDFLAGS_gcc)
CPU_ASRCS += $(CPU_ASRCS_gcc)
CPU_CSRCS += $(CPU_CSRCS_gcc)
CPU_CXXSRCS += $(CPU_CXXSRCS_gcc)
CPU_EOBJS += $(CPU_EOBJS_gcc)

SOC_INCDIRS += $(SOC_INCDIRS_gcc)
SOC_AFLAGS += $(SOC_AFLAGS_gcc)
SOC_CFLAGS += $(SOC_CFLAGS_gcc)
SOC_CXXFLAGS += $(SOC_CXXFLAGS_gcc)
SOC_LDFLAGS += $(SOC_LDFLAGS_gcc)
SOC_ASRCS += $(SOC_ASRCS_gcc)
SOC_CSRCS += $(SOC_CSRCS_gcc)
SOC_CXXSRCS += $(SOC_CXXSRCS_gcc)
SOC_EOBJS += $(SOC_EOBJS_gcc)

BRD_INCDIRS += $(BRD_INCDIRS_gcc)
BRD_AFLAGS += $(BRD_AFLAGS_gcc)
BRD_CFLAGS += $(BRD_CFLAGS_gcc)
BRD_CXXFLAGS += $(BRD_CXXFLAGS_gcc)
BRD_LDFLAGS += $(BRD_LDFLAGS_gcc)
BRD_ASRCS += $(BRD_ASRCS_gcc)
BRD_CSRCS += $(BRD_CSRCS_gcc)
BRD_CXXSRCS += $(BRD_CXXSRCS_gcc)
BRD_EOBJS += $(BRD_EOBJS_gcc)

EINCDIRS += $(EINCDIRS_gcc)
ELIBS += $(ELIBS_gcc)

ifeq ($(ARCHCFG_LITTLE_ENDIAN),y)
  ENDIAN := little-endian
else
  ENDIAN := big-endian
endif
D ?= 1
WARN := -Wall -Wextra -Wundef -Wsign-conversion -Werror
WARN += -Wno-cast-function-type -Wno-error=unused-parameter
INCDIRS = -I. \
          -I$(XWOS_ARCH_DIR) \
          -I$(XWOS_CPU_DIR) \
          -I$(XWOS_SOC_DIR) \
          -I$(XWOS_BRD_DIR)

PERDEF = -D__XWOS__

AFLAGS = -mabi=aapcs -mno-thumb-interwork -m$(ENDIAN) -mthumb \
         -nostdinc -nostdlib -mno-unaligned-access \
         -ffunction-sections -fdata-sections \
         -g -g3 -gdwarf-4 -fvar-tracking -fvar-tracking-assignments \
         -Wa,-adhlns="$@.lst" $(WARN) $(PERDEF)

CFLAGS = -mabi=aapcs -mthumb -std=gnu18 \
         -fomit-frame-pointer -mno-thumb-interwork -m$(ENDIAN) \
         -mno-unaligned-access \
         -ffunction-sections -fdata-sections -ftls-model=local-exec \
         -g -g3 -gdwarf-4 -fvar-tracking -fvar-tracking-assignments -fverbose-asm \
         -Wa,-adhlns="$@.lst" $(WARN) $(PERDEF)

CXXFLAGS = -mabi=aapcs -mthumb -std=gnu++17 \
           -fomit-frame-pointer -mno-thumb-interwork -m$(ENDIAN) \
           -mno-unaligned-access \
           -ffunction-sections -fdata-sections -ftls-model=local-exec \
           -g -g3 -gdwarf-4 -fvar-tracking -fvar-tracking-assignments -fverbose-asm \
           -Wa,-adhlns="$@.lst" $(WARN) $(PERDEF)

MMFLAGS = -MM -MP

ifeq ($(O),)
  ifeq ($(D),0)
    O := 1
  else
    O := g
  endif
endif

CFLAGS += -O$(O)
CXXFLAGS += -O$(O)

LDFLAGS = -mthumb -mabi=aapcs -m$(ENDIAN) \
          -L$(XWOS_SOC_DIR) -T$(XWOS_BRD_DIR)/$(XWCFG_LDSCRIPT) \
          -Wl,--allow-multiple-definition -Wl,--gc-sections \
          -Wl,-z,noexecstack \
          -Wl,-Map=$(XWOS_WKSPC_DIR)/$(TARGET).map,--cref

# colorfully build
SHOW_CPP =
SHOW_CC =
SHOW_CXX =
SHOW_APP =
SHOW_AS =
SHOW_OD =
SHOW_OBJCOPY =
SHOW_MM =
SHOW_AR =
SHOW_LD =
SHOW_SIZE =
SHOW_LUA2HEX =
SHOW_CP =

ifeq ($(XWCFG_HOSTOS),gnu/linux)
  ifneq ($(V),1)
    SHOW_CPP = @$(MSG) "\e[1m\e[44;38m[cc -E] "$<" -> "$@" \e[0m";
    SHOW_CC = @$(MSG) "\e[1m\e[44;38m[cc] "$<" -> "$@" \e[0m";
    SHOW_CXX = @$(MSG) "\e[1m\e[44;38m[c++] "$<" -> "$@" \e[0m";
    SHOW_APP = @$(MSG) "\e[1m\e[44;38m[as -E] "$<" -> "$@" \e[0m";
    SHOW_AS = @$(MSG) "\e[1m\e[44;38m[as] "$<" -> "$@" \e[0m";
    SHOW_OD = @$(MSG) "\e[1m\e[40;38m[od] "$<" -> "$@" \e[0m";
    SHOW_OBJCOPY = @$(MSG) "\e[1m\e[47;34m[objcopy] "$<" -> "$@" \e[0m";
    SHOW_MM = @$(MSG) "\e[1m\e[46;38m[mm] "$<" -> "$@" \e[0m";
    SHOW_AR = @$(MSG) "\e[1m\e[42;38m[ar] "$@" \e[0m";
    SHOW_LD = @$(MSG) "\e[1m\e[47;34m[ld] "$@" \e[0m";
    SHOW_SIZE = @$(MSG) "\e[1m\e[47;34m[size] "$@" \e[0m";
    SHOW_LUA2HEX = @$(MSG) "\e[1m\e[47;34m[lua2hex] "$@" \e[0m";
    SHOW_CP = @$(MSG) "\e[1m\e[47;34m[cp] "$<" -> "$@" \e[0m";
  endif
endif

ifeq ($(XWCFG_HOSTOS),darwin)
  ifneq ($(V),1)
    SHOW_CPP = @$(MSG) "\e[1m\e[44;38m[cc -E] "$<" -> "$@" \e[0m";
    SHOW_CC = @$(MSG) "\e[1m\e[44;38m[cc] "$<" -> "$@" \e[0m";
    SHOW_CXX = @$(MSG) "\e[1m\e[44;38m[c++] "$<" -> "$@" \e[0m";
    SHOW_APP = @$(MSG) "\e[1m\e[44;38m[as -E] "$<" -> "$@" \e[0m";
    SHOW_AS = @$(MSG) "\e[1m\e[44;38m[as] "$<" -> "$@" \e[0m";
    SHOW_OD = @$(MSG) "\e[1m\e[40;38m[od] "$<" -> "$@" \e[0m";
    SHOW_OBJCOPY = @$(MSG) "\e[1m\e[47;34m[objcopy] "$<" -> "$@" \e[0m";
    SHOW_MM = @$(MSG) "\e[1m\e[46;38m[mm] "$<" -> "$@" \e[0m";
    SHOW_AR = @$(MSG) "\e[1m\e[42;38m[ar] "$@" \e[0m";
    SHOW_LD = @$(MSG) "\e[1m\e[47;34m[ld] "$@" \e[0m";
    SHOW_SIZE = @$(MSG) "\e[1m\e[47;34m[size] "$@" \e[0m";
    SHOW_LUA2HEX = @$(MSG) "\e[1m\e[47;34m[lua2hex] "$@" \e[0m";
    SHOW_CP = @$(MSG) "\e[1m\e[47;34m[cp] "$<" -> "$@" \e[0m";
  endif
endif

ifeq ($(XWCFG_HOSTOS),windows-nt)
  ifneq ($(V),1)
    SHOW_CPP = @$(MSG) "[cc -E] "$<" -> "$@;
    SHOW_CC = @$(MSG) "[cc] "$<" -> "$@;
    SHOW_CXX = @$(MSG) "[c++] "$<" -> "$@;
    SHOW_APP = @$(MSG) "[as -E] "$<" -> "$@;
    SHOW_AS = @$(MSG) "[as] "$<" -> "$@;
    SHOW_OD = @$(MSG) "[od] "$<" -> "$@;
    SHOW_OBJCOPY = @$(MSG) "[objcopy] "$<" -> "$@;
    SHOW_MM = @$(MSG) "[mm] "$<" -> "$@;
    SHOW_AR = @$(MSG) "[ar] "$@;
    SHOW_LD = @$(MSG) "[ld] "$@;
    SHOW_SIZE = @$(MSG) "[size] "$@;
    SHOW_LUA2HEX = @$(MSG) "[lua2hex] "$@;
    SHOW_CP = @$(MSG) "[cp] "$@;
  endif
endif
